BehaviourView = class("BehaviourView");

function BehaviourView:Awake(obj)
    self.viewName = ''
    self.gameObject = obj;
    self.transform = obj.transform;
    self.luaBehaviour = obj:GetComponent('LuaBehaviour')
end

function BehaviourView:OnShow()
    self:AddListeners();
    self:ResumeAllCoroutineA()
    UpdateBeat:Add(self.Update, self)
    FixedUpdateBeat:Add(self.FixedUpdate, self)
    LateUpdateBeat:Add(self.LateUpdate, self)
end

function BehaviourView:OnHide()
    self:RemoveListeners()
    self:ClearCoroutine()
    self:PauseAllCoroutineA()
    self:ClearTimer()
    UpdateBeat:Remove(self.Update, self)
    FixedUpdateBeat:Remove(self.FixedUpdate, self)
    LateUpdateBeat:Remove(self.LateUpdate, self)
end
function BehaviourView:Update() end
function BehaviourView:FixedUpdate() end
function BehaviourView:LateUpdate() end
function BehaviourView:AddListeners() end
function BehaviourView:RemoveListeners() end

--coroutine
function BehaviourView:StartCoroutine(func)
    if self.coroutines == nil then
        self.coroutines = {}
    end

    local co = coroutine.start(function()
        func()
        table.remove_value(self.coroutines, coroutine.running())
    end)
    table.insert(self.coroutines, co)

    return co
end

function BehaviourView:StartCoroutineA(func)
    if self.coroutinesA == nil then
        self.coroutinesA = {}
    end

    local co = coroutine.start(function()
        func()
        table.remove_value(self.coroutinesA, coroutine.running())
    end)
    table.insert(self.coroutinesA, co)

    return co
end

function BehaviourView:PauseAllCoroutineA()
    if self.coroutinesA then
        for _, co in pairs(self.coroutinesA) do
            coroutine.pause(co)
        end
    end
end

function BehaviourView:ResumeAllCoroutineA()
    if self.coroutinesA then
        for _, co in pairs(self.coroutinesA) do
            coroutine.resume(co)
        end
    end
end

function BehaviourView:StopCoroutine(co)
    table.remove_value(self.coroutines, co)
    coroutine.stop(co)
end

function BehaviourView:StopCoroutineA(co)
    table.remove_value(self.coroutinesA, co)
    coroutine.stop(co)
end

function BehaviourView:ClearCoroutine()
    if self.coroutines then
        for _, co in pairs(self.coroutines) do
            coroutine.stop(co)
        end
    end

    self.coroutines = {}
end

function BehaviourView:ClearCoroutineA()
    if self.coroutinesA then
        for _, co in pairs(self.coroutinesA) do
            coroutine.stop(co)
        end
    end

    self.coroutinesA = {}
end

--timer
function BehaviourView:Interval(func, interval, rep)
    if self.timers == nil then
        self.timers = {}
    end

    local timer = TIMERM.Interval(func, self, interval, rep)
    table.insert(self.timers, timer)
    return timer
end

function BehaviourView:Step(func, step, rep)
    if self.timers == nil then
        self.timers = {}
    end

    local timer = TIMERM.Step(func, self, step, rep)
    table.insert(self.timers, timer)
    return timer
end

function BehaviourView:Kill(timer)
    timer.remove = true
    table.remove_value(self.timers, timer)
end

function BehaviourView:ClearTimer()
    if self.timers then
        for _, timer in pairs(self.timers) do
            timer.remove = true
        end
    end
    self.timers = {}
end

function BehaviourView:OnDestroy()
    self:ClearCoroutine()
    self:ClearCoroutineA()
    self:ClearTimer()

    for k, v in pairs(self) do
        if type(v) == 'userdata' then
            self[k] = nil
        end
    end
end